home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
PET
/
S-Super PET
/
(s)tj.d64
/
KEY1.2.ASM
< prev
next >
Wrap
Assembly Source File
|
2009-01-18
|
25KB
|
558 lines
opt nolist
MemEnd_ equ $22 ;As defined by Waterloo
Service_ equ $32 ;As defined by Waterloo
irq_ equ $0108 ;As defined by Waterloo
ACIAstatus equ $eff1 ;As defined in the SuperPET's hardware
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| K E Y B O A R D I N I T I A L I Z A T I O N S |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
stiffness equ $01 ;pause period between two consequtive pia reads
repeat_delay equ $1e ; 30 jiffies = 1/2 second ($1e in Waterloo code)
repeat_cont equ $03 ; 3 jiffies = 1/20 second
keyboard_init equ * ;called to connect keyboard
clr Service_ ;set exit mode to TRUE when done
ldd #top_mem ;set Waterloo's top of memory
std MemEnd_
ldb #stiffness ;set keyboard stiffness
stb debounce
ldb #repeat_delay ;select cold repeat frequency
stb long_pause
ldb #repeat_cont
stb short_pause ;select warm repeat frequency
ldd #$ffff ;used by verification routine
std old_up_coord
std old_down_coord
std prev_coord
stb keyb_enable ;enable the keyboard
ldd #irq_service_routine
std irq_ ;link keyboard to IRQ service routine
top_mem rts
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| D A T A S E C T I O N (W I L L B E M O V E D I N O S / 9) |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
hours equ $0160 ;will be moved elsewhere in OS/9
hours_max equ 24 ;24 hrs. clock
clock_status equ $e813 ;bit 7 is set on clock interrupt (1/60 sec.).
pia_row equ $e810 ;writing a number between 0-9 will select a row
pia_col equ $e812 ;reading the port clears the clock interrupt
;and will return the column of the selected row
keyb_enable equ $0129 ;will be moved elsewhere in OS/9
long_pause rmb $01 ;maximum delay (in jiffies) before repeat starts
short_pause rmb $01 ;maximum delay (in jiffies) while repeating
debounce rmb $01 ;will control stiffness of keyboard
delay rmb $01 ;counter used for repeat key function
prev_coord rmb $02 ;last column/row of previous key
prev_key rmb $01 ;last ASCII value of previous key
old_up_coord rmb $02 ;used for 2 keys roll over recognition
old_down_coord rmb $02 ;up = scanned up, down = scanned down
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| I N T E R R U P T H A N D L E R |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
irq_service_routine equ *
ldb clock_status ;clock interrupts every 1/60 sec (bit 7)
if lt
bsr clock ;update real time clock
bsr keyboard ;scan keyboard and update buffer
ldb pia_col
else
ldb ACIAstatus ;clear ACIA interrupts (or add an ACIA driver)
endif
rts
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| C L O C K D R I V E R |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
clock equ * ;update the real time clock
ldx #hours+4 ;X = pointer+4 to (hrs,min,sec,jiffies)
ldd #60*256+4 ;A = base 60 ,B = 4 digit to update
loop
inc ,-x ;point to next digit and increment it
cmpa ,x ;compare 60 againt it ; similar code to that
quif hi ; provided by A. Moise
clr ,x ;do modulo 60 add ; in console.asm
decb ; on (S)TB
until eq ;update no more than 4 digits, for safety.
decb ;if all 4 digits were updated
if le ;then correct the hours
lda #hours_max ;24 hours per day
cmpa ,x ;x points to hours
if ls
clr ,x ;do modulo 24 add
; ___________________________________________________________________
; / \
;| ;update the day of the month |
;| lbsr calendar ;update the day of the week |
;| ;update the month and year |
; \___________________________________________________________________/
endif
endif
rts
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| A D D A C H A R A C T E R T O K E Y B O A R D B U F F E R |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
; to be replace in OS/9
; add_char_to_buffer
; Accumulator B contains the character to be added to
; the keyboard buffer
; All registers are restored to their original value.
kyptr1_ equ $012c ; address of buffer pointer 1 (to be moved)
kyptr2_ equ $012e ; address of buffer pointer 2 (to be moved)
kybuf_ equ $0130 ; address of start of buffer (to be moved)
kybuflen_ equ $28 ; length of buffer
add_char_to_buffer equ * ;to be updated for OS/9 use
pshs d,x,cc
sei
ldx kyptr2_
leax 1,x ; increment the pointer
cmpx #kybuf_+kybuflen_ ; past end of buffer?
if eq
ldx #kybuf_ ; wrap around to start of buffer
endif
cmpx kyptr1_ ; is the buffer filled?
if ne
stb [kyptr2_] ; save the character in the buffer
stx kyptr2_ ; update pointer 2
endif
puls d,x,cc,pc ;restore registers, enable interrups
;return from subroutine
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| K E Y B O A R D H A N D L E R |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
keyboard equ * ;scan the keyboard and update the keyboard
;buffer if necessary
ldb keyb_enable ;is the keyboard enabled?
if ne ;$00 = disabled, $ff = enabled
bsr scan_keyboard ;return key's coordinates
if eq ;cc = zero if no key is depressed
std prev_coord ;ensure that the next key will be treated
lda long_pause ; as a new one
sta delay
else ;cc <> zero therefore a key is depressed
cmpd prev_coord
if eq ;was this key depressed during last interrupt ?
dec delay
if eq ;if delay time had elapsed
lda short_pause
sta delay
ldb prev_key
bsr add_char_to_buffer
endif
else ;this key is different from the last one
std prev_coord
lbsr convert_to_ascii
stb prev_key
bsr add_char_to_buffer
lda long_pause
sta delay
endif
endif
else
ldb #9 ;re-enable the keyboard by
stb pia_row ;pressing "_" and STOP simultaneously
ldb pia_col
eorb #%11101110 ;will be 0 iff "RUN" + "_"
if eq
com keyb_enable
endif
endif
rts
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| K E Y B O A R D S C A N N E R |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
; This routine is called to determine if a key is depressed
; and if so, determine its row/column address on the keyboard,
; then set the condition code register to reflect results.
; OFF/RVS, left, right and lock SHIFT keys are control keys.
; ALL the remaining keys are non-control, but may be FUNCTION keys.
; Results - If no key is depressed or only the control keys are
; depressed then return
; D = $FFFF
; CC= zero flag set
; If the OFF/RVS key is depressed, bit 7 of reg A is set
; If ANY SHIFT key is depressed, bit 7 of reg B is set
; If BOTH OFF/RVS and SHIFT keys are depressed, OFF/RVS
; is assumed
; If any non-control key is depressed then return
; A = row number (0 to 9) , bit 7 set accordingly
; B = column number (0 to 7) , bit 7 set accordingly
; CC= zero flag cleared
scan_keyboard equ *
; Offsets to temporary variables with respect to the stack pointer
shift_row equ 6 ;row number of shift keys
rvs_row equ 8 ;row number of OFF/RVS key
shift_mask equ %01000001 ;column positions of shift keys
rvs_mask equ %00000001 ;column position of OFF/RVS key
shift_flag equ 11 ;offset to shift status on stack
rvs_flag equ 10 ;offset to OFF/RVS status on "
row equ 12 ;hold offset for row number
column equ row+1 ;hold offset for column number
results equ row ;offset for row,column
leas -(10+2+2),s ;open room for 10 debounced row images
; + 2 status bytes (RVS,shift)
; + 2 result bytes (row,column)
lda #9 ;___ record keyboard image...
loop ; \
bsr get_col ; \ debounce and read all
stb a,s ; > columns of all 10 rows
deca ; / and store them on the stack
until lt ;___/
ldd #shift_mask ;___
andb shift_row,s ; \
if ne ; \ set shift status and
eorb shift_row,s ; \ mask it in keyboard image
stb shift_row,s ; >
lda #$80 ; /
endif ; /
sta shift_flag,s ;___/ shift_flag is $80 if shifted, 0 if not
ldd #rvs_mask ;___
andb rvs_row,s ; \
if ne ; \ set OFF/RVS status and
eorb rvs_row,s ; \ mask it
stb rvs_row,s ; \
clr shift_flag,s ; /if (OFF/RVS + shift) then OFF/RVS only
lda #$80 ; /
endif ; /
sta rvs_flag,s ;___/ rvs_flag is $80 if depressed, 0 if not
lda #9
loop
ldb a,s ;A = row number, B = row's contents
quif ne ;quit when a key is sensed
deca
until lt ;until all rows exhosted
tstb
if eq
ldd #$ffff ;no non-control key is depressed
else
ora rvs_flag,s ;A <-- row number + OFF/RVS status
sta row,s ;record the row and OFF/RVS status
lda #8 ;compute column number
loop
deca
aslb ;C <-- b7.....b0 <-- 0
until cs ;done when carry is set since B<>0
ora shift_flag,s ;A <-- column number + shift status
sta column,s ;record column number+ shift status
ldd results,s ;results point to rvs_glag,shift_flag
bsr verify_coord ;verify coordinates and allow for rollover
endif
leas (10+2+2),s ;remove all temporary storage
cmpd #$ffff ;set CC register
rts
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| D E B O U N C E A R O W T H E N R E A D C O L U M N S |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
get_col equ * ;read columns of the row pointed to by the contents
;of the A accumulator
;return
; A = unchanged
; B = bit map of the columns in this row
; 1 bit set for each key depressed
; CC= zero if no key in this row depressed
; <>zero otherwise
sta pia_row ;select a row pointed to by A
pshs a
loop ;___
ldb pia_col ; \
lda debounce ; \
loop ; \
deca ; > debounce keyboard
until eq ; /
cmpb pia_col ; /
until eq ;___/
comb ;set cc and return result
puls a,pc ;restore A and return from subroutine
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| M A T R I X C O O R D I N A T E S T O A S C I I C O N V E R S I O N |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
; convert_to_ascii
; Input - Accumulator A contains the keyboard row number
; bit 7 is set if the OFF/RVS key was depressed
; Accumulator B contains the keyboard column number
; bit 7 is set if the left, right or lock SHIFT key was depressed
; Result - Accumulator B contains the character representation corresponding
; to keyboard's row/column address
convert_to_ascii equ *
shift_offset equ 80
control_offset equ shift_offset + 80
pshs x,b ;preserve x register
;save register B for now
; no need to get rid of control flag in
; accumulator A, since it represents 4 orders
; of magnitute shift w.r.t the row number
; which is less than 10 (one nibble)
ldb #$08
mul ; D <-- ($80*RVS + row)*8 A = $04*RVS , B= row*8
leax ascii_table,pc
abx ; x = address of table + 8 * row (abx since row*8<80)
puls b ; now we are ready to use the column information
tsta ; if A <> 0 then RVS flag was set before multiplication
if ne
leax control_offset,x
else
tstb
if lt
leax shift_offset,x
endif
endif
andb #$7f ; get rid of the shift status
ldb b,x ; get the ascii character
clra
puls x,pc ;return from subroutine
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| V E R I F Y M A C R O F O R K E Y B O A R D C O O R D I N A T E S |
;| and 2 K E Y S R O L L O V E R G E N E R A T O R (optional) |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
; Will verify correctness of coordinates and
; check for 2 keys rool over
; may be omitted if it causes too much overhead
; Verification is done be reading the matrix coordinates
; backwards.
; If the resultant coordinates are in agreement with the
; original set then return the original set.
; If the interpretation depends on the way we read the matrix,
; then
; if any of the coordinates equals to the last set
; then
; return the one which is not the same
; else
; return $ffff, rejecting this result.
verify_coord equ * ;On entry D = new_up_coord
;On exit D = verified coordinates
pshs y,x,d ;D = new_up_coord , save X and Y
;0,S = D = new_up_coord
;2,S = X
;4,S = Y
;6,S = PC
;8,S = keyboard image
ldb #7 ;point to one byte prior to first row
loop ;start the scan with row 0
incb
lda b,s
until ne ;A = columns, B = row when done
subb #8
orb rvs_flag+8,s ;add OFF/RVS attribute to the row
pshs b
ldb #-1 ;generate column number
loop ;using right hand rotation
incb
lsra
until cs ;B = column number when done
puls a ;A <-- (OFF/RVS flag + row number)
orb shift_flag+8,s ;B <-- (shift flag + column number)
;D = new_down_coord
cmpd 0,s ;[0,S] = new_up_coord
if eq ;if (new_up = new_down)
std old_up_coord
std old_down_coord
else
ldy 0,s ;Y = new_up_coord
tfr d,x ;X = new_down_coord
guess ;\ if
cmpx old_down_coord ; \ (old_down_coord =
quif ne ; \ new_down_coord )
; > &
cmpy old_up_coord ; / (old_up_coord =
quif ne ; / new_up_coord )
ldd prev_coord ;/ then return prev_coord
admit ; else go on
cmpy old_up_coord
if eq ;if (new_up=old_up) then
tfr x,d ; return new_down_coord
else ;else
cmpx old_down_coord
if eq ; if (old_down=new_down) then
tfr y,d ; return new_up_coord
else ; else
ldd #-1 ; return $ffff
tfr d,x
tfr d,y
endif ; endif
endif ;endif
endguess ; endif
stx old_down_coord
sty old_up_coord
endif
leas 2,s
puls x,y,pc
end
; __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
; / \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \
;| SuperPET and Commodore 8032 Keyboard matrix map |
; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
ascii_table equ * ;will be change to suit OS/9
; Lower Case Keyboard values
; <-- columns -->
; 0 1 2 3 4 5 6 7 rows 0 1 2 3 4 5 6 7
fcb '2 ,'5 ,'8 ,'- ,'8 ,$07,$ff,$ff ;0| 2 5 8 - *8 ==>
fcb '1 ,'4 ,'7 ,'0 ,'7 ,'^ ,$ff,'9 ;1| 1 4 7 0 *7 ^ *9
fcb $06,'s ,'f ,'h ,'] ,'k ,'; ,'5 ;2| ESC s f h ] k ; *5
fcb 'a ,'d ,'g ,'j ,$0d,'l ,'@ ,'6 ;3| a d g j CR l @ *6
fcb $09,'w ,'r ,'y ,'\ ,'i ,'p ,$04 ;4| TAB w r y \ i p DEL
fcb 'q ,'e ,'t ,'u ,$0a,'o ,'[ ,'4 ;5| q e t u CRDWN o [ *4
fcb $ff,'c ,'b ,'. ,'. ,$ff,$ff,'3 ;6|SHIFT c b . *. SHIFT *3
fcb 'z ,'v ,'n ,', ,'0 ,$ff,$7f,'2 ;7| z v n , *0 RUB *2
fcb $ff,'x ,$20,'m ,$01,$ff,'/ ,'1 ;8|RVS x SP m HOME / *1
fcb '_ ,'3 ,'6 ,'9 ,$03,': ,$ff,$ff ;9| _ 3 6 9 STOP :
; * a character preceded by an asterisk
; is on the keypaad
; Upper Case Keyboard values
; <-- columns -->
; 0 1 2 3 4 5 6 7 rows 0 1 2 3 4 5 6 7
fcb '" ,'% ,'( ,'= ,$88,$08,$ff,$ff ;0| " % ( = f8 <== .. ..
fcb '! ,'$ ,'' ,'0 ,$87,'~ ,$ff,$89 ;1| ! $ ' 0 f7 ~ f9
fcb $06,'S ,'F ,'H ,'} ,'K ,'+ ,$85 ;2|EEOL S F H } K + f5
fcb 'A ,'D ,'G ,'J ,$0d,'L ,'` ,$86 ;3| A D G J CR L ` f6
fcb $09,'W ,'R ,'Y ,'| ,'I ,'P ,$05 ;4| TAB W R Y | I P INST
fcb 'Q ,'E ,'T ,'U ,$0b,'O ,'{ ,$84 ;5| Q E T U CRSUP O { f4
fcb $ff,'C ,'B ,'> ,$8b,$ff,$ff,$83 ;6|SHIFT C B > f. ..SHIFT f3
fcb 'Z ,'V ,'N ,'< ,$8a,$ff,$7f,$82 ;7| Z V N < f0 .. RUB f2
fcb $ff,'X ,$20,'M ,$0c,$ff,'? ,$81 ;8|RVS X SP M CLR .. ? f1
fcb '_ ,'# ,'& ,') ,$02,'* ,$ff,$ff ;9| _ # & ) RUN * .. ..
; a character preceded by an f
; is on the keypad
; Control characters Keyboard values
; <-- columns -->
; 0 1 2 3 4 5 6 7 rows 0 1 2 3 4 5 6 7
fcb '2 ,'5 ,'8 ,'- ,$93,$07,$ff,$ff ;0| 2 5 8 - F8 ==> .. ..
fcb '1 ,'4 ,'7 ,$80,$92,$1e,$ff,$94 ;1| 1 4 7 BRK F7 ^^ .. F9
fcb $06,$81,$06,$08,$1d,$0b,'; ,$90 ;2|EEOL ^s ^f ^h ^] ^k ; F5
fcb $01,$85,$7f,$0a,$0d,$0c,$00,$91 ;3| ^a ^d ^g ^j CR ^l ^@ F6
fcb $09,$17,$12,$19,$1c,$09,$10,$04 ;4| TAB ^w ^r ^y ^\ ^i ^p DEL
fcb $83,$05,$89,$87,$0a,$86,$1b,$8f ;5| ^q ^e ^t ^u CRDWN^o ^[ F4
fcb $ff,$8b,$07,'. ,$96,$ff,$ff,$8e ;6|SHIFT^c ^b . F. ..SHIFT F3
fcb $82,$88,$84,', ,$95,$ff,$7f,$8d ;7| ^z ^v ^n , F0 .. RUB F2
fcb $ff,$18,$20,$0d,$01,$ff,'/ ,$8c ;8|RVS ^x SP ^m HOME .. / F1
fcb $1f,'3 ,'6 ,'9 ,$ff,': ,$ff,$ff ;9| ^_ 3 6 9 STOP : .. ..
; a character preceded by an F
; is on the keypad
end